package com.fingard.net.niosocket;

import java.io.UnsupportedEncodingException;
import java.nio.channels.SocketChannel;
import java.util.HashMap;

import com.fingard.text.StringHelper;

public class HttpNioReceiver extends NioReceiver{

	public HttpNioReceiver(SocketChannel p_socketChannel, String p_defCharset) {
		super(p_socketChannel, p_defCharset);
		headKV = new HashMap<String, String>();
	}
	
    private static byte headCut1Cr = '\r';//"\\r".getBytes("gbk")[0];
    private static byte headCut2Lf = '\n';//"\\n".getBytes("gbk")[0];
    
    public HashMap<String, String> headKV;
    
    public String visitPage;
    public String httpMethod;
    
    private String charset;
    
    public void setCharset(String p_charset){
    	charset = p_charset;
    	defCharset = p_charset;
    }
    
    public String getCharset(){
    	if(StringHelper.hasAnyChar(charset)){
    		return charset;
    	}else{
    		if(headKV.containsKey("content-type")){
    			String ctype = headKV.get("content-type").toLowerCase();
    			String[] typevals = ctype.split(";");
    			for(int i=0;i<typevals.length;i++){
    				if(typevals[i].contains("charset")){
    					String[] matvals = typevals[i].split("=");
    					if(matvals.length>1){
    						charset = matvals[1];
    						return charset;
    					}
    				}
    			}
    		}
    		//Content-Type: text/plain;charset=UTF-8
    		charset = defCharset;
    		return defCharset;
    	}
    }
    
	@Override
	public void getHeader() throws UnsupportedEncodingException{
        if (contentLength < 0 || contentStartIndex < 0){
            if (receiveOffSet > 2048){
            	errMsg = "未知的通讯头部：" + new String(recBytes, 0, receiveOffSet, defCharset);
            	contentStartIndex = -1;
            	hasError = true;
            	return;
            }
            for (int i = readHeadStartIndex; i < readedLength; i++) {
                if (recBytes[i] == headCut2Lf) {// 是\n
                    int tmpEndCount = i - readHeadStartIndex;
                    if (i > 1 && recBytes[i - 1] == headCut1Cr){// 前一个字符是\r
                    	tmpEndCount--;
                    }
                    String tmpHeadStr = new String(recBytes, readHeadStartIndex, tmpEndCount, defCharset);
                    String tmpKey = "";
                    String tmpValue = "";
                    
                    int idx1 = tmpHeadStr.indexOf(":");
                    if(idx1>0){
                    	tmpKey = tmpHeadStr.substring(0,idx1).toLowerCase().trim();
                    	tmpValue = tmpHeadStr.substring(idx1+1).toLowerCase().trim();
                    }else{
                    	tmpKey = tmpHeadStr.toLowerCase().trim();
                    }
                    headKV.put(tmpKey, tmpValue);
                    if ("content-length".equals(tmpKey)) {
                        contentLength = Integer.valueOf(tmpValue);
                    }
                    readHeadStartIndex = i + 1;
                    ////POST /notify HTTP/1.1
                    if (StringHelper.isNullOrEmpty(visitPage)) {
                        String headPage = tmpHeadStr.toLowerCase();
                        if (headPage.startsWith("post") || headPage.startsWith("get") || headPage.startsWith("head")) {
                            String[] pValues = tmpHeadStr.split(" ");
                            httpMethod = pValues[0].toLowerCase();
                            if (pValues.length > 1) {
                                visitPage = pValues[1];
                            }
                        }
                    }

                    if ((i < readedLength - 1 && recBytes[i + 1] == headCut2Lf) ||
                            (i < readedLength - 2 && recBytes[i + 2] == headCut2Lf)) {
                        contentStartIndex = i+1;
                        if(recBytes[i + 2] == headCut2Lf){
                        	contentStartIndex = i+3;
                        }
                        if("get".equals(httpMethod)){
                        	if(this.contentLength<0){
                        		this.contentLength = 0;
                        	}
                        }
                        break;
                    }
                }
            }
        }
	}
}
